home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Xconq 7.0d37 / source / misc / per2g < prev    next >
Encoding:
Text File  |  1994-05-13  |  13.6 KB  |  427 lines  |  [TEXT/R*ch]

  1. #!/usr/local/bin/perl
  2. eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
  3.     if $running_under_some_shell;
  4.  
  5. require "getopts.pl";
  6. &Getopts('o:');
  7. die "Usage: per2g [-o outfile] [infile]\n" if @ARGV > 1;
  8.  
  9. #
  10. # Get stdout set up and the default module name
  11. #
  12. if ( $opt_o ) {
  13.     #
  14.     # If they give us an output file name, open it
  15.     # and use it as the module name (minus path and extension).
  16.     #
  17.     open(STDOUT, ">$opt_o") || die "Couldn't open $opt_o for output: $!\n";
  18.     ($m = $opt_o) =~ s#(.*/)?(.*)\.g$#$2#;
  19. } elsif (@ARGV) {
  20.     #
  21.     # If they give us an input file,
  22.     # use it as the output file name (minus path and extension plus .g)
  23.     # and use it as the module name (minus path and extension).
  24.     #
  25.     ($m = $ARGV[0]) =~ s#(.*/)?(.*)\.per$#$2#;
  26.     unless ( -e "$m.g" ) {
  27.     open(STDOUT, ">$m.g") || die "Couldn't open $m.g for output: $!\n";
  28.     }
  29. } else {
  30.     #
  31.     # OK, we got nothin', output is stdout and module name is junk.
  32.     #
  33.     $m = 'xxx';
  34. }
  35.  
  36. $c_prefix = ';FIX ';
  37.  
  38. %drop = (
  39.     'attrition-damage',        1,
  40.     'dark',            1,
  41.     'discipline-effect',    1,
  42.     'first-unit',        1,
  43.     'first-product',        1,
  44.     'maker',            1,
  45.     'named',            1,
  46.     'neutrality',        1,
  47.     'random-move',        1,
  48.     'scale',            1,
  49.     'nuke-hit',            1,
  50.     'accident-message',        0,
  51.     'alt-roughness',        0,
  52.     'wet-roughness',        0,
  53.     'attack-worth',        0,
  54.     'attrition-message',    0,
  55.     'conceal',            0,
  56.     'defense-worth',        0,
  57.     'destroy-message',        0,
  58.     'disaster-message',        0,
  59.     'explore-worth',        0,
  60.     'font-name',        0,
  61.     'make',            0,
  62.     'min-region-size',        0,
  63.     'neutral',            0,
  64.     'nuked',            0,
  65.     'research',            0,
  66.     'siege',            0,
  67.     'starve-message',        0,
  68. );
  69.  
  70. %vars = (
  71.     'all-seen',            'see-all',
  72.     'edge-terrain',        'edge-terrain',
  73.     'country-size',        'country-radius-min',
  74.     'country-min-distance',    'country-separation-min',
  75.     'country-max-distance',    'country-separation-max',
  76.     'spy-chance',        'spy-chance',
  77.     'spy-quality',        'spy-quality',
  78. );
  79.  
  80. %props = (
  81.     'already-seen',        'already-seen',
  82.     'always-seen',        'see-always',
  83.     'changes-side',        'acp-to-change-side',
  84.     'hold-volume',        'capacity',
  85.     'hp',            'hp-max',
  86.     'in-country',        'start-with',
  87.     'max-alt',            'alt-percentile-max',
  88.     'max-wet',            'wet-percentile-max',
  89.     'min-alt',            'alt-percentile-min',
  90.     'min-wet',            'wet-percentile-min',
  91.     'revolt',            'revolt-chance',
  92.     'see-best',            'vision-at-max-range',
  93.     'see-range',        'vision-at',
  94.     'see-worst',        'vision-range',
  95.     'self-destruct',        'acp-to-detonate',
  96.     'territory',        'point-value',
  97.     'max-quality',        'cxp-max',
  98.     'skill-effect',        'cxp-hit-effect',
  99.     'discipline-effect',    'cxp-hit-effect',
  100. );
  101.  
  102. %tables = (
  103.     'accident',            'accident-hit-chance',
  104.     'disaster',            'accident-vanish-chance',
  105.     'alter-mobility',        'mp-per-occupant',
  106.     'attrition',        'attrition',
  107.     'bridge',            'ferry-on-entry',
  108.     'capacity',            'occupant-max',
  109.     'capture',            'capture-chance',
  110.     'consume',            'base-consumption',
  111.     'damage',            'damage',
  112.     'defense',            'defend-terrain-effect',
  113.     'enter-time',        'mp-to-enter-unit',
  114.     'favored',            'favored-terrain',
  115.     'hit',            'hit-chance',
  116.     'hit-by',            'hit-by',
  117.     'hits-with',        'consumption-per-attack',
  118.     'in-length',        'in-length',
  119.     'leave-time',        'mp-to-leave-unit',
  120.     'moves',            'mp-to-enter-terrain',
  121.     'out-length',        'out-length',
  122.     'produce',            'base-production',
  123.     'productivity',        'productivity',
  124.     'protect',            'protection',
  125.     'repair',            'hp-per-repair',
  126.     'stockpile',        'supply-on-completion',
  127.     'storage',            'unit-storage-x',
  128.     'to-make',            'material-to-build',
  129.     'to-move',            'consumption-per-move',
  130. );
  131.  
  132. %lists = (
  133.     'can-counter',        'acp-to-defend',
  134.     'can-disband',        'hp-per-disband',
  135.     'combat-time',        'acp-to-attack',
  136.     'consume-as-occupant',    'consumption-as-occupant',
  137.     'crippled',            'hp-at-min-speed',
  138.     'density',            'independent-density',
  139.     'occupant-produce',        'occupant-base-production',
  140.     'retreat',            'withdraw-chance-per-attack',
  141.     'speed',            'speed',
  142.     'startup',            'tp-to-build',
  143.     'surrender',        'surrender-chance',
  144.     'survival',            'hp-per-starve',
  145.     'visibility',        'visibility',
  146.     'volume',            'unit-size-as-occupant',
  147. );
  148.  
  149. %comments = (
  150.     'attack-worth',    "dunno if this is still useful for AIs",
  151.     'defense-worth',    "dunno if this is still useful for AIs",
  152.     'explore-worth',    "dunno if this is still useful for AIs",
  153.     'min-region-size',    "dunno if this is still useful for AIs",
  154.     'alt-roughness',    "this is broken into alt-blob-size, etc. etc.",
  155.     'wet-roughness',    "this is broken into wet-blob-size, etc. etc.",
  156.     'accident',        "accident is U T -> .01N chance that an accident happens to U\n; and you can set accident-damage",
  157.     'acp-to-defend',    "acp-to-defend is U1 U2 -> ACP, set to 0 to disable counter-attacks",
  158.     'attrition',    "attrition is U T -> .01HP (rate of loss, hp/turn)",
  159.     'bridge',        "ferry-on-entry is U1 U2 -> FTYPE how much terrain U2 crosses to board U1",
  160.     'can-disband',    "hp-per-disband is U1 U2 -> HP lost in a disband action performed by U2\n; you might add U1 acp-to-disband U2 as well, U1 U2 -> ACP",
  161.     'capacity',        "occupant-max is U1 U2 -> N upper limit on occupants by type",
  162.     'combat-time',    "acp-to-attack U1 U2 -> ACP for U1 to attack U2",
  163.     'conceal',        "conceal is now visibility, you should subtr these numbers from that table",
  164.     'crippled',        "in addition you can set hp-to-repair and other things to cripple a unit",
  165.     'hold-volume',    "capacity is N, upper limit on total occupants by size",
  166.     'make',        "make is replaced by acp-to-create, cp-per-build and friends",
  167.     'moves',        "moves is mp-to-{enter|leave}-terrain U T -> MP",
  168.     'nuked',        "I guess nuked is damaged-terrain now, T1 T2 -> N",
  169.     'occupant-produce',    "occupant-base-production is U M -> N of M that U produces as occupant",
  170.     'repair',        "hp-per-repair is U1 U2 -> .01HP that U1 restores to U2 per repair action\n; ...and you have to add...\n; acp-to-repair is U1 U2 -> ACP to do one repair action",
  171.     'research',        "this is handled by tech level and research now...",
  172.     'retreat',        "U1 U2 -> % that U2 withdraws before U1 attacks",
  173.     'see-best',        "vision-at is N, coverage afforded by unit in its own hex",
  174.     'see-worst',    "vision-at-max-range is N, coverage afforded by unit at max range",
  175.     'speed',        "don't forget to add acp-per-turn for non-movers!",
  176.     'spy-chance',    "spy-chance is now on a per unit basis...\n; and spy-range specifies how far a unit can spy",
  177.     'spy-quality',    "spy-quality is U1 U2 -> % that U1 returns info about U2",
  178.     'startup',        "tp-to-build is U1 U2 -> TP that U1 needs before building U2\n; you also need UnitProperty acp-to-toolup and Table tp-per-toolup",
  179.     'stockpile',    "this used to be % now it is a raw number.",
  180.     'surrender',    "surrender is U1 U2 -> .01N chance that U1 surrenders to U2\n; and surrender-range is distance at which it can occur",
  181.     'survival',        "survival is now hp-per-starve U M -> HP",
  182.     'visibility',    "visibility is U T -> N, U's % visibility in T",
  183.     'volume',        "unit-size-as-occupant is U1 U2 -> N U1's size as occupant of U2",
  184. );
  185.  
  186. $\ = "\n";        # automatically add newline on print
  187.  
  188. LINE:
  189. while (<>) {
  190.     # strip leading/trailing whitespace (and the newline).
  191.     s/^\s+//;
  192.     s/\s+$//;
  193.  
  194.     # transform () to []
  195.     tr/[]/()/;
  196.     # change r* (resources) to m* (materials)
  197.     s/r\*/m*/g;
  198.  
  199.     # Grab the comment off the end of the line...
  200.     s/\s*(;.*)$//;
  201.     $trail = "$1";
  202.  
  203.     # blank line...
  204.     unless ( $_ ) {
  205.     # ...it may be a terminator for sname or uname...
  206.     print('))'), $in_name = 0 if $in_namer;
  207.     # ...actually it coulda been a comment.
  208.     print "$trail";
  209.     next LINE;
  210.     }
  211.  
  212.     if (/^Xconq . [\+-]+ (.*)$/) {
  213.     # This is the file starter.
  214.     # Now we KNOW we're in the right kinda file.
  215.     print qq/(game-module "$m"\n  (blurb "$1")\n)/;
  216.     next LINE;
  217.  
  218.     } elsif (/(.*) period-name$/) {
  219.     print qq/(game-module (title $1))/, ($trail)? "\t$trail" : '';
  220.     next LINE;
  221.  
  222.     } elsif ( /Period [01]/ ) {
  223.     next LINE;
  224.  
  225.     } elsif ( /begin{notes}/ ) {
  226.     print("(game-module (notes");
  227.     ++$seen_key{'notes'};
  228.     while (<>) {
  229.         print("))"), last if /end{notes}/;
  230.     }
  231.     next LINE;
  232.  
  233.     } elsif (/\s*"(.)"\s+"(.*)"\s+"(.*)"\s+(.)type$/) {
  234.     if ( $4 eq 'u' ) {
  235.         $u = $1;    # ($u = $2) =~ y/A-Z/a-z/;
  236.         $utype{$1} = $u;
  237.         if ( $defines{'u*'} ) {
  238.         $defines{'u*'} .= " $1";
  239.         } else {
  240.         $defines{'u*'} = "$1";
  241.         }
  242.         print "$trail" if $trail;
  243.         print qq/(unit-type $u (name "$2") (char "$1")\n  (help "$3")\n)/;
  244.     } elsif ( $4 eq 'r' ) {
  245.         print qq/(material-type |$2| (help "$3"))/, ($trail)? "\t$trail" : '';
  246.     } elsif ( $4 eq 't' ) {
  247.         print qq/(terrain-type |$2| (char "$1") (color "$3"))/, ($trail)? "\t$trail" : '';
  248.     }
  249.     next LINE;
  250.  
  251.     } elsif (/(.*)\s+(.*)\s+icon-name$/) {
  252.     print "(add $utype{$2} image-name $1)", ($trail)? "\t$trail" : '';
  253.     next LINE;
  254.  
  255.     } elsif (/(.*)\s+"(.*)"\s+define$/) {
  256.     $defines{$2} = $1;
  257.     print "(define $2 $1)", ($trail)? "\t$trail" : '';
  258.     next LINE;
  259.  
  260.     } elsif (/clear-(\S*)-names$/) {
  261.     print "(namer $1-names (random", ($trail)? "\t$trail" : '';
  262.     ++$in_namer;
  263.     next LINE;
  264.  
  265.     } elsif (/[su]name/) {
  266.     s/[su]name\s?//g;
  267.     s/\*/ /g;
  268.     print;
  269.     next LINE;
  270.  
  271.     } elsif (/^end$/) {
  272.     # ain't no mo...
  273.     last;
  274.     }
  275.  
  276.     #
  277.     # strip the last word off the line and see if we can
  278.     # find it in our list of keywords.
  279.     #
  280.     split;
  281.     $key = pop(@_);
  282.     next LINE if $drop{$key};
  283.  
  284.     print $c_prefix, $comments{$key} if $comments{$key} && !$seen_key{$key}++;
  285.  
  286.     if ( $vars{$key} ) {
  287.     m/^(.*) $key$/;
  288.  
  289.     # These are special cases that don't quite match
  290.     # or need additional processing...
  291.     if ($key eq 'spy-chance') {
  292.         local($val) = ($1 eq 'true')? 10 : ($1 eq 'false')? 0 : $1;
  293.         print "(add u* $vars{$key} $1)", ($trail)? "\t$trail" : '';
  294.         next LINE;
  295.     } elsif ($key eq 'spy-quality') {
  296.         local($val) = ($1 eq 'true')? 10 : ($1 eq 'false')? 0 : $1;
  297.         print "(table $vars{$key} (u* u* $1))", ($trail)? "\t$trail" : '';
  298.         next LINE;
  299.     }
  300.  
  301.     print "(set $vars{$key} $1)", ($trail)? "\t$trail" : '';
  302.     next LINE;
  303.  
  304.     } elsif ( $props{$key} ) {
  305.     m/(^[^ ()]*|\(.*\))\s+([^ ()]*|\(.*\))\s+$key$/;
  306.     local($val) = ($1 eq 'true')? 1 : ($1 eq 'false')? 0 : $1;
  307.  
  308.     # These are special cases that don't quite match
  309.     # or need additional processing...
  310.     if ($key eq 'revolt') {
  311.         push(@random_events, 'units-revolt');
  312.     }
  313.  
  314.     print "(add $2 $props{$key} $val)", ($trail)? "\t$trail" : '';
  315.     next LINE;
  316.  
  317.     } elsif ( $lists{$key} ) {
  318.     m/(^[^ ()]*|\(.*\))\s+([^ ()]*|\(.*\))\s+$key$/;
  319.  
  320.     # @vals = split(/\s+/, ($defines{$1})? $defines{$1} : $1);
  321.     # @typs = split(/\s+/, ($defines{$2})? $defines{$2} : $2);
  322.     # shift(@vals), pop(@vals) if @vals[0] eq '(';
  323.     # shift(@typs), pop(@typs) if @typs[0] eq '(';
  324.  
  325.     # These are special cases that don't quite match
  326.     # or need additional processing...
  327.     if ($key eq 'surrender') {
  328.         push(@random_events, 'units-surrender') unless $seen_key{$key}++;
  329.     } elsif ($key eq 'consume-as-occupant' || $key eq 'survival') {
  330.         print "(table $lists{$key} add ($2 m* $1))", ($trail)?"\t$trail":'';
  331.         next LINE;
  332.     } elsif ($key eq 'startup' || $key eq 'retreat') {
  333.         print "(table $lists{$key} add (u* $2 $1))", ($trail)?"\t$trail":'';
  334.         next LINE;
  335.     } elsif ($key eq 'can-disband') {
  336.         print "; (table $lists{$key} add ($2 u* 100))", ($trail)?"\t$trail":'';
  337.         next LINE;
  338.     } elsif ($key eq 'occupant-produce') {
  339.         local($v) = ($1 =~ /true/i)? 1 : 0;
  340.         print "(table $lists{$key} add ($2 m* $v))", ($trail)?"\t$trail":'';
  341.         next LINE;
  342.     } elsif ($key eq 'visibility' || $key eq 'density') {
  343.         print "(table $lists{$key} add ($2 t* $1))", ($trail)?"\t$trail":'';
  344.         next LINE;
  345.     } elsif ($key eq 'crippled') {
  346.         print "(add $2 $lists{$key} $1)";
  347.         next LINE;
  348.     } elsif ($key eq 'speed') {
  349.         print "(add $2 acp-per-turn $1)\n(add $2 $lists{$key} 100)";
  350.         next LINE;
  351.     }
  352.  
  353.     print "(table $lists{$key} add ($2 u* $1))", $trail ? "\t$trail" : '';
  354.     next LINE;
  355.  
  356.     } elsif ( $tables{$key} ) {
  357.     m/^([^ ()]*|\(.*\))\s+([^ ()]*|\(.*\))\s+([^ ()]*|\(.*\))\s+$key$/;
  358.     local($val) = $1;
  359.  
  360.     # These are special cases that don't quite match
  361.     # or need additional processing...
  362.     if ($key eq 'attrition') {
  363.         push(@random_events, 'attrition-in-terrain') unless $seen_key{$key}++;
  364.     } elsif ($key eq 'accident') {
  365.         push(@random_events, 'accidents-in-terrain') unless $seen_key{$key}++;
  366.     } elsif ($key eq 'bridge') {
  367.         $val = 'over-all';
  368.     } elsif ($key eq 'defense' || $key eq 'protect') {
  369.         local(@vals, $i);
  370.         $val =~ s/\s*[()]\s*//g;
  371.         @vals = split(/\s+/, $val);
  372.         foreach $i (@vals) {
  373.         $i = 100 - $i;
  374.         }
  375.         $val = join(' ', @vals);
  376.         $val =~ s/^(.*)$/($1)/ if @vals > 1;
  377.     } elsif ($key eq 'moves') {
  378.         local(@vals, $i);
  379.         $val =~ s/\s*[()]\s*//g;
  380.         @vals = split(/\s+/, $val);
  381.         foreach $i (@vals) {
  382.         if ( $i < 0 ) {
  383.             $i = 99;
  384.         } else {
  385.             ++$i;
  386.         }
  387.         }
  388.         $val = join(' ', @vals);
  389.         $val =~ s/^(.*)$/($1)/ if @vals > 1;
  390.     } elsif ($key eq 'repair') {
  391.         print "(table acp-to-repair add ($3 $2 1))";
  392.         local(@vals, $i);
  393.         if ( $val =~ /[()]/ ) {
  394.         @vals = split(/\s+/, $val);
  395.         for ($i = 1; $i < @vals - 1; ++$i) {
  396.             @vals[$i] = 1 unless @vals[$i];
  397.             @vals[$i] = int(100 / @vals[$i]);
  398.         }
  399.         $val = join(' ', @vals);
  400.         } else {
  401.         $val = int(100 / $val);
  402.         }
  403.     }
  404.  
  405.     print "(table $tables{$key} add ($3 $2 $val))", ($trail)?"\t$trail":'';
  406.     next LINE;
  407.  
  408.     } elsif ( !defined($drop{$key}) ) {
  409.     print STDERR "Unknown keyword: $key" unless $unkey{$key}++;
  410.     }
  411.  
  412.     # turn everything else into a comment,
  413.     # so that we don't throw any important bits away.
  414.     print $c_prefix, $_, ($trail)? "\t$trail" : '';
  415. }
  416.  
  417. print "\n;(set random-events (@random_events))" if @random_events;
  418.  
  419. print "
  420. (game-module (instructions (
  421.   )))
  422. (game-module (design-notes (
  423.   )))";
  424. print "(game-module (notes (\n)))" unless $seen_key{'notes'};
  425.  
  426. exit(0);
  427.